;  TAKE OUT DEBUGGING OCCH 
; 
	PAGE 60,132
	TITLE SORTBB - BETTER BASIC INTERFAC TO S30 SORTRES - SORTBB
;==============================================================================
;SORTBB.ASM
;
;INPUT 
;	BETTER BASIC CALL STRUCTURES OBJECT STACK FRAMES
;PROCESS
;	VERY EXPLICIT SPECIAL CODING AND ADDRESSING REQUIRED TO ACCESS PARMS
;	PICK UP PARMS AND TRANSLATE TO S30 PARMBLK REQUIREMENTS
;	INCLUDES PARMAMETER BLOCK REFERENCES LAST PARM FIRST
; 	ALL STRINGS STORED BACKWARDS (EG 'TAD.PMAS') SO RESEQUENCE &
;	STORE COPY FOR _MAINS WITHIN INTERFACE'S CODE SECTION   
;	CALL SORTRES INTERRUPT
;	RETURN TO BETTER BASIC
;OUTPUT
;	S30 PARMBLK STRUCTURE
;
;NOTES: MODULE MUST BE CONVERTED TO *.BIN FILE WHICH IS DECLARED IN A SPECIAL
;	CODE "sortbb.BIN" STATEMENT REQUIRED AT TOP OF BETTER BASIC PROGRAM.
;-----------------------------------------------------------------------------
;
; DEFINE BETTER BASICS OBJECT STACK FRAME LOCATIONS

FRAME		EQU	12H		;AS REQUIRED BY BETTER BASIC
OBJ@PREC	EQU WORD PTR -50H	;#of bytes for real
TXT@DISP	EQU WORD PTR -4EH	;offset
TXT@SEG		EQU WORD PTR -4CH	;segment
OBJ@SIZE	EQU WORD PTR -4AH	;string size
OBJ@DISP	EQU WORD PTR -48H	;offset to string length
OBJ@SEG		EQU WORD PTR -46H	;segment of string length
OBJ@PTR		EQU DWORD PTR -48H	;
TXT@PTR		EQU DWORD PTR -4EH	;
; ----------------------------------------------------------
;
CODE	SEGMENT		 
	ASSUME  CS:CODE,DS:CODE,ES:CODE ;PER BETTER BASIC
	ORG 	0			;PER BETTER BASIC
SYM1	DB	SYM2-$			;LINK TO NEXT SYMBOL TABLE
	DB	'SORTBB'		;NAME OF PROCEDURE
	DW	0			;FILL WORD, MUST BE HERE
	DW	HEADER1			;POINT TO PROCEDURE HEADER
;
SYM2	DB	0			;SYMBOL TABLE TERMINATOR
;
	EVEN				;HEADERS MUST BE ON WORD BOUNDARY
HEADER1	DW	154H			;MUST BE 154H !!!
	DW	SORTBB			;POINTER TO ACTUAL ASSEMBLER PROC
	DW	5			;NUMBER OF ARGUMENTS
	DW	3			;TYPE OF ARGUMENT 0
	DW	3			;TYPE OF ARGUMENT 1
	DW	3			;TYPE OF ARGUMENT 2
	DW	1			;TYPE OF ARGUMENT 3 	
	DW	1			;TYPE OF ARGUMENT 4
; 
	INCLUDE	PARMBLK.STR			;STRUCTURE OF S30 PARM BLOCK
;
PB	PARMBLK	<>			;ALLOCATE PARMBLOCK MEMORY
;
MAX_INFILE_LEN	EQU	670		;MAX LENGTH 10 FILENAMES + " + "s
MAX_OUTFILE_LEN	EQU	64		;MAX LENGTH 1 FILENAME
MAX_CTLSTMT_LEN EQU	1001		;MAX LENGTH - ARBITRARY
;					
;					SPACE TO PUT INFILE NAME FOR SORT
INFILE_NAME	DB	MAX_INFILE_LEN DUP (?)	
;					SPACE TO PUT OUTFILE NAME FOR SORT
OUTFILE_NAME	DB	MAX_OUTFILE_LEN DUP(?)	
;					SPACE FOR CTLSTMT FOR SORT
CTLSTMT_STR 	DB	MAX_CTLSTMT_LEN DUP(?)	
;
;????	EXTRN	_MAINS:FAR 
	PUBLIC 	SORTBB 			;
SORTBB	PROC FAR			;MUST BE A FAR PROC
;	DB	0CCH			;STOP
;GET RETCODE
	LDS	BX,OBJ@PTR[BP]		;GET POINTER TO LAST VARIABLE
	MOV	CS:PB.RETCODE_SEG,DS	;PUT RETCODE SEG INTO PB
	MOV	CS:PB.RETCODE_OFF,BX	;PUT RETCODE OFF INTO PB
;GET NUMREC
	LDS	BX,OBJ@PTR[BP-FRAME]	;GET POINTER TO NUMREC
	MOV	CS:PB.NUMREC_SEG,DS	;PUT NUMREC SEG INTO PB
	MOV	CS:PB.NUMREC_OFF,BX	;PUT NUMREC OFF INTO PB
;
;GET CTLSTMT STORED BACKWARDS BY BETTERBASIC 
	LDS     BX,OBJ@PTR[BP-24H]	;GET POINTER TO CTLSTMT LENGTH
	MOV	CX,DS:[BX]		;PUT LENGTH INTO CX
	MOV	CS:PB.CTLSTMT_LEN,CX	;PUT CTLSTMT LENGTH IN PB
	LES	SI,TXT@PTR[BP-24H]	;GET CTLSTMT PARM ADDRESS 
	MOV	CS:PB.CTLSTMT_SEG,CS	;PUT CTLSTMT SEGMENT IN PB
	MOV     DI,OFFSET CTLSTMT_STR	;GET OFFSET POINTER TO INDEX REG
	MOV	CS:PB.CTLSTMT_OFF,DI	;SAVE OFFSET OF CTLSTMT
	CMP	CS:[PB].CTLSTMT_LEN,MAX_CTLSTMT_LEN	;IS IT TOO LONG?
	JB	CTL1			;JUMP TO CTL1 IF LENGTH OK - ELSE
	JMP	BB_920			;JMP TO ERROR SECTION
CTL1:	
	MOV	AL,BYTE PTR ES:[SI]	;PICK UP FIRST BYTE OF BACKWARDS NAME
	MOV	CS:[DI],AL		;PUT INTO NEW AREA IN RIGHT ORDER
	INC	DI			;INCREMENT DI FOR DESTINATION SEQUENCE
	DEC	SI			;DECREMENT SI AS SOURCE TO BACKWARD STR
	LOOP	CTL1			;CONTINUE FOR LENGTH IN CX
;
;GET OUTFILE
	LDS     BX,OBJ@PTR[BP-36H]	;GET POINTER TO OUTFILE LENGTH
	MOV	CX,DS:[BX]		;PUT LENGTH INTO CX FOR FUTURE COUNTING
	MOV	CS:PB.OUTFILE_LEN,CX	;PUT OUTFILE LENGTH IN PB

	LES	SI,TXT@PTR[BP-36H]	;GET ADDRESS OF BACKWARDS OUTFILE NAME
	MOV	CS:PB.OUTFILE_SEG,CS	;PUT OUTFILE SEGMENT IN PB
	MOV	DI,OFFSET OUTFILE_NAME	;GET OFFSET OF NEW OUTFILE NAME TO AX
	MOV	CS:PB.OUTFILE_OFF,DI	;PUT NEW OUTFILE OFFSET INTO PB
	CMP	CS:[PB].OUTFILE_LEN,MAX_OUTFILE_LEN	;IS IT TOO LONG?
	JA	BB_920			;JMP TO ERROR SECTION
OUT1:	
	MOV	AL,BYTE PTR ES:[SI]	;PICK UP FIRST BYTE OF BACKWARDS NAME
	MOV	CS:[DI],AL		;PUT INTO NEW AREA IN RIGHT ORDER
	INC	DI			;INCREMENT DI FOR DESTINATION SEQUENCE
	DEC	SI			;DECREMENT SI AS SOURCE TO BACKWARD STR
	LOOP 	OUT1			;CONTINUE FOR LENGTH IN CX
;
;GET INFILE
	LDS     BX,OBJ@PTR[BP-48H]	;GET POINTER TO INFILE LENGTH
	MOV	CX,DS:[BX]		;PUT LENGTH INTO CX FOR FUTURE COUNTING
	MOV	CS:PB.INFILE_LEN,CX	;PUT INFILE LENGTH IN PB
	LES	SI,TXT@PTR[BP-48H]	;GET ADDRESS OF BACKWARDS INFILE NAME
	MOV	CS:PB.INFILE_SEG,CS	;PUT INFILE SEGMENT IN PB
	MOV	DI,OFFSET INFILE_NAME	;GET OFFSET OF NEW INFILE NAME TO DI
	MOV	CS:PB.INFILE_OFF,DI	;PUT NEW INFILE OFFSET INTO PB
	CMP	CS:[PB].INFILE_LEN,MAX_INFILE_LEN	;IS IT TOO LONG?
	JA      BB_920			;JMP TO ERROR SECTION
IN1:	
	MOV	AL,BYTE PTR ES:[SI]	;PICK UP FIRST BYTE OF BACKWARDS NAME
	MOV	CS:[DI],AL		;PUT INTO NEW AREA IN RIGHT ORDER
	INC	DI			;INCREMENT DI FOR DESTINATION SEQUENCE
	DEC	SI			;DECREMENT SI AS SOURCE TO BACKWARD STR
	LOOP 	IN1			;CONTINUE FOR LENGTH IN CX
;
;CHECK IF RESIDENT SORT IS LOADED --------------------------------
	PUSH	DS			;SAVE DS VALUE
	SUB	AX,AX			;CLEAR AX
	MOV	DS,AX			;SET ZERO SEG REGISTER
	MOV	AX,DS:[7DH*4]		;GET CONTENTS OF SORTRES INT VECTOR
	POP	DS			;RESTORE DS VALUE
	CMP	AX,2			;IS SORTRES LOADED?
	JE	BB_200			;YES - CONTINUE
	JMP	BB_930			;ERROR - SORTRES NOT LOADED
;
BB_200:
;NOW CALL SORT ----------------------
	PUSH	CS			;PUT CS ON STACK SO CAN POP INTO DS
	POP	DS			;POP CS IN DS 
	LEA	DX,PB			;GET OFFSET OF PB
	INT	7DH			;SORTRES ROUTINE
	JMP	BB_999			;EXIT AND RETURN
;	
;ERROR CODES --------------------------------------------------------
;
BB_920:
;SORT PARAMETER STRINGS ARE TOO LONG ---
	PUSH	BX			;SAVE BX VALUE
	MOV	BX,CS:[PB].RETCODE_OFF	;GET OFFSET OF RETURN CODE
	MOV	ES,CS:[PB].RETCODE_SEG	;GET RETCODE SEGEMNT INTO ES
	MOV	WORD PTR ES:[BX],270	;SET ERROR CODE
	MOV	BX,CS:[PB].NUMREC_OFF	;GET OFFSET TO NUMBER OF RECORDS
	MOV	ES,CS:[PB].NUMREC_SEG	;GET SEGMENT TO NUMREC VALUE
	MOV	WORD PTR ES:[BX],0	;SET NUMBER OF RECORDS TO 0
	POP	BX			;RESTORE BX
	JMP	BB_999			;LEAVE
;
BB_930:
;SORTRES NOT LOADED ---------------------
	PUSH	BX			;SAVE BX VALUE
	MOV	BX,CS:[PB].RETCODE_OFF	;GET OFFSET OF RETURN CODE
	MOV	ES,CS:[PB].RETCODE_SEG	;GET RETCODE SEGEMNT INTO ES
	MOV	WORD PTR ES:[BX],390	;SET ERROR CODE
	MOV	BX,CS:[PB].NUMREC_OFF	;GET OFFSET TO NUMBER OF RECORDS
	MOV	ES,CS:[PB].NUMREC_SEG	;GET SEGMENT TO NUMREC VALUE
	MOV	WORD PTR ES:[BX],0	;SET NUMBER OF RECORDS TO 0
	POP	BX			;RESTORE BX
	JMP	BB_999			;LEAVE
;NOW RETURN ------------------------------------------------------------
BB_999:
	CLC
	RET				;SIMPLE RETURN NO STACK PROBLEMS
SORTBB	ENDP
CODE	ENDS
	END

